1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  package com.google.common.hash;
16  
17  import com.google.common.annotations.Beta;
18  import com.google.common.base.Preconditions;
19  
20  import java.io.OutputStream;
21  import java.io.Serializable;
22  import java.nio.charset.Charset;
23  
24  import javax.annotation.Nullable;
25  
26  
27  
28  
29  
30  
31  
32  @Beta
33  public final class Funnels {
34    private Funnels() {}
35  
36    
37  
38  
39    public static Funnel<byte[]> byteArrayFunnel() {
40      return ByteArrayFunnel.INSTANCE;
41    }
42  
43    private enum ByteArrayFunnel implements Funnel<byte[]> {
44      INSTANCE;
45  
46      public void funnel(byte[] from, PrimitiveSink into) {
47        into.putBytes(from);
48      }
49  
50      @Override public String toString() {
51        return "Funnels.byteArrayFunnel()";
52      }
53    }
54  
55    
56  
57  
58  
59  
60  
61  
62    public static Funnel<CharSequence> unencodedCharsFunnel() {
63      return UnencodedCharsFunnel.INSTANCE;
64    }
65  
66    private enum UnencodedCharsFunnel implements Funnel<CharSequence> {
67      INSTANCE;
68  
69      public void funnel(CharSequence from, PrimitiveSink into) {
70        into.putUnencodedChars(from);
71      }
72  
73      @Override public String toString() {
74        return "Funnels.unencodedCharsFunnel()";
75      }
76    }
77  
78    
79  
80  
81  
82  
83  
84    public static Funnel<CharSequence> stringFunnel(Charset charset) {
85      return new StringCharsetFunnel(charset);
86    }
87  
88    private static class StringCharsetFunnel implements Funnel<CharSequence>, Serializable {
89      private final Charset charset;
90  
91      StringCharsetFunnel(Charset charset) {
92        this.charset = Preconditions.checkNotNull(charset);
93      }
94  
95      public void funnel(CharSequence from, PrimitiveSink into) {
96        into.putString(from, charset);
97      }
98  
99      @Override public String toString() {
100       return "Funnels.stringFunnel(" + charset.name() + ")";
101     }
102 
103     @Override public boolean equals(@Nullable Object o) {
104       if (o instanceof StringCharsetFunnel) {
105         StringCharsetFunnel funnel = (StringCharsetFunnel) o;
106         return this.charset.equals(funnel.charset);
107       }
108       return false;
109     }
110 
111     @Override public int hashCode() {
112       return StringCharsetFunnel.class.hashCode() ^ charset.hashCode();
113     }
114 
115     Object writeReplace() {
116       return new SerializedForm(charset);
117     }
118 
119     private static class SerializedForm implements Serializable {
120       private final String charsetCanonicalName;
121 
122       SerializedForm(Charset charset) {
123         this.charsetCanonicalName = charset.name();
124       }
125 
126       private Object readResolve() {
127         return stringFunnel(Charset.forName(charsetCanonicalName));
128       }
129     
130       private static final long serialVersionUID = 0;
131     }
132   }
133 
134   
135 
136 
137 
138 
139   public static Funnel<Integer> integerFunnel() {
140     return IntegerFunnel.INSTANCE;
141   }
142 
143   private enum IntegerFunnel implements Funnel<Integer> {
144     INSTANCE;
145 
146     public void funnel(Integer from, PrimitiveSink into) {
147       into.putInt(from);
148     }
149 
150     @Override public String toString() {
151       return "Funnels.integerFunnel()";
152     }
153   }
154 
155   
156 
157 
158 
159 
160 
161   public static <E> Funnel<Iterable<? extends E>> sequentialFunnel(Funnel<E> elementFunnel) {
162     return new SequentialFunnel<E>(elementFunnel);
163   }
164 
165   private static class SequentialFunnel<E> implements Funnel<Iterable<? extends E>>, Serializable {
166     private final Funnel<E> elementFunnel;
167 
168     SequentialFunnel(Funnel<E> elementFunnel) {
169       this.elementFunnel = Preconditions.checkNotNull(elementFunnel);
170     }
171 
172     public void funnel(Iterable<? extends E> from, PrimitiveSink into) {
173       for (E e : from) {
174         elementFunnel.funnel(e, into);
175       }
176     }
177 
178     @Override public String toString() {
179       return "Funnels.sequentialFunnel(" + elementFunnel + ")";
180     }
181 
182     @Override public boolean equals(@Nullable Object o) {
183       if (o instanceof SequentialFunnel) {
184         SequentialFunnel<?> funnel = (SequentialFunnel<?>) o;
185         return elementFunnel.equals(funnel.elementFunnel);
186       }
187       return false;
188     }
189 
190     @Override public int hashCode() {
191       return SequentialFunnel.class.hashCode() ^ elementFunnel.hashCode();
192     }
193   }
194 
195   
196 
197 
198 
199 
200   public static Funnel<Long> longFunnel() {
201     return LongFunnel.INSTANCE;
202   }
203   
204   private enum LongFunnel implements Funnel<Long> {
205     INSTANCE;
206     
207     public void funnel(Long from, PrimitiveSink into) {
208       into.putLong(from);
209     }
210     
211     @Override public String toString() {
212       return "Funnels.longFunnel()";
213     }
214   }
215   
216   
217 
218 
219 
220 
221 
222 
223 
224 
225 
226   public static OutputStream asOutputStream(PrimitiveSink sink) {
227     return new SinkAsStream(sink);
228   }
229   
230   private static class SinkAsStream extends OutputStream {
231     final PrimitiveSink sink;
232     SinkAsStream(PrimitiveSink sink) {
233       this.sink = Preconditions.checkNotNull(sink);
234     }
235     
236     @Override public void write(int b) {
237       sink.putByte((byte) b);
238     }
239 
240     @Override public void write(byte[] bytes) {
241       sink.putBytes(bytes);
242     }
243 
244     @Override public void write(byte[] bytes, int off, int len) {
245       sink.putBytes(bytes, off, len);
246     }
247     
248     @Override public String toString() {
249       return "Funnels.asOutputStream(" + sink + ")";
250     }
251   }
252 }